package top.xiaoazi.futureletterserver.module.verifycode.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.xiaoazi.futureletterserver.common.FileStoreVariable;
import top.xiaoazi.futureletterserver.common.R;
import top.xiaoazi.futureletterserver.module.verifycode.entity.VerifyCode;
import top.xiaoazi.futureletterserver.module.verifycode.service.VerifyCodeService;
import top.xiaoazi.futureletterserver.module.verifycode.vo.VerifyCodeVO;
import top.xiaoazi.futureletterserver.utils.FileUtils;
import top.xiaoazi.futureletterserver.utils.RedisKeyUtils;
import top.xiaoazi.futureletterserver.utils.RedisUtils;
import top.xiaoazi.futureletterserver.utils.RequestUtils;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Random;

@RestController
@RequestMapping("/verify-code")
public class VerifyCodeController {

    private final String PREV_PATH = "/api/image/" + FileStoreVariable.IMAGE_VERIFY_CODE + "/";
    private final String SAVE_PATH = FileStoreVariable.BASE_PATH + FileStoreVariable.IMAGE_VERIFY_CODE;

    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private RequestUtils requestUtils;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 添加一个验证码
     * @param imgFile
     * @param result
     * @return
     */
    @PostMapping("/sys/add")
    public R add(@RequestParam(value = "imgPath", required = false) MultipartFile imgFile,
                 @RequestParam("result") String result) throws IOException {
        // 1. 创建两个文件
        String imgFileName = null;
        if (imgFile != null) {
            imgFileName = FileUtils.save(imgFile, SAVE_PATH);
            imgFileName = PREV_PATH + imgFileName;
        } else {
            return R.success(requestUtils.BAD_REQUEST_STATE, requestUtils.BAD_REQUEST_MESSAGE);
        }
        // 2. 保存好文件后开始插入数据库
        VerifyCode verifyCode = new VerifyCode();
        verifyCode.setImgPath(imgFileName);
        verifyCode.setResult(result);
        verifyCodeService.add(verifyCode);
        return R.success("增加成功");
    }

    /**
     * 更新验证码信息
     * @return
     */
    @PostMapping("/sys/update")
    public R update(@RequestParam(value = "imgPath", required = false) MultipartFile imgFile,
                    @RequestParam("result") String result,
                    @RequestParam("id") Integer id) throws IOException {
        // 1. 如果是修改，肯定是存在广告id
        if (id == null || id <= 0) {
            return R.success(requestUtils.BAD_REQUEST_STATE, requestUtils.BAD_REQUEST_MESSAGE);
        }
        VerifyCode verifyCode = verifyCodeService.getById(id);
        // 2. 删除本地存储的文件, 保存新的图片
        if (imgFile != null) {
            FileUtils.delete(SAVE_PATH,
                    verifyCode.getImgPath().substring(verifyCode.getImgPath().lastIndexOf('/') + 1));
            String imgFileName = FileUtils.save(imgFile, SAVE_PATH);
            verifyCode.setImgPath(PREV_PATH + imgFileName);
        }
        // 3. 更新 result
        verifyCode.setResult(result);
        // 4. service 操作更新
        verifyCodeService.update(verifyCode);
        return R.success("更新成功");
    }

    /**
     * 删除验证码信息
     * @param verifyCode
     * @return
     */
    @PostMapping("/sys/del")
    public R del(@RequestBody VerifyCode verifyCode) {
        if (verifyCode.getId() == null) {
            return R.success(requestUtils.BAD_REQUEST_STATE, requestUtils.BAD_REQUEST_MESSAGE);
        }
        verifyCode = verifyCodeService.getById(verifyCode.getId());
        // 1. 删除文件
        FileUtils.delete(SAVE_PATH,
                verifyCode.getImgPath().substring(verifyCode.getImgPath().lastIndexOf('/') + 1));
        // 2. 删除数据库内容
        verifyCodeService.del(verifyCode);
        return R.success("删除成功");
    }

    /**
     * 获取所有验证码, 这个接口仅仅管理员可用
     * @return
     */
    @GetMapping("/sys/get-list")
    public R getList() {
        String key = RedisKeyUtils.getVerifyCodeListKey();
        if (redisUtils.hasKey(key)) {
            return R.success(redisUtils.get(key));
        } else {
            List<VerifyCode> verifyCodes = verifyCodeService.getList();
            redisUtils.set(key, verifyCodes);
            return R.success(verifyCodes);
        }
    }

    @GetMapping("/get-code")
    public R getCode() throws JsonProcessingException {
        List<VerifyCodeVO> list = null;
        // 2. 返回数据
        list = verifyCodeService.getListVO();
        Collections.shuffle(list);
        if (list.size() == 0) {
            R.success(new VerifyCodeVO());
        }
        Random random = new Random();
        int randomIndex = random.nextInt(list.size());
        return R.success(list.get(randomIndex));
    }

    /**
     * 通过 id 获取验证码
     */
    @GetMapping("/get-verify-code")
    public R getVerifyCode(Integer id) {
        String code = verifyCodeService.getVerifyCode(id);
        return R.success(code);
    }
}
